package com.oweight.sagacious.auth.server.domain.service.spring;

import com.oweight.sagacious.auth.server.domain.entity.Client;
import com.oweight.sagacious.auth.server.domain.repo.ClientRepository;
import com.oweight.sagacious.auth.server.domain.service.IClientServiceManager;
import com.oweight.sagacious.auth.server.domain.valobj.ClientInfo;
import com.oweight.sagacious.auth.server.infrastructure.util.client.ClientTokenUtil;
import com.oweight.sagacious.common.exception.auth.ClientInvalidException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 周广明
 * @version v1 2019/10/30 14:03
 */
@Service
public class ClientServiceManager implements IClientServiceManager {

    @Autowired
    private ClientRepository clientRepository;

    @Autowired
    private ClientTokenUtil clientTokenUtil;

    @Autowired
    private DiscoveryClient discovery;

    @Override
    public String apply(String clientId, String secret) throws Exception {
        Client client = getClient(clientId, secret);
        return clientTokenUtil.generateToken(new ClientInfo(client.getFdCode(), client.getFdName(), client.getFdId()));
    }

    @Override
    public void validate(String clientId, String secret) throws Exception {
        Client client = clientRepository.findByFdCode(clientId);
        if (client == null || !client.getFdSecret().equals(secret)) {
            throw new ClientInvalidException("Client not found or Client secret is error!");
        }
    }

    @Override
    public List<String> getAllowedClient(String clientId, String secret) {
        Client client = this.getClient(clientId, secret);
        List<String> clients = clientRepository.selectAllowedClient(client.getFdId());
        if (clients == null) {
            return new ArrayList<>();
        }
        return clients;
    }

    @Override
    public List<String> getAllowedClient(String serviceId) {
        Client client = getClient(serviceId);
        List<String> clients = clientRepository.selectAllowedClient(client.getFdId());
        if (clients == null) {
            return new ArrayList<>();
        }
        return clients;
    }

    @Override
    @Scheduled(cron = "0 0/1 * * * ?")
    public void registryClient() {
        // 自动从注册中心获取客户端并在系统中注册
        discovery.getServices().forEach((name) -> {
            Client client = new Client();
            client.setFdName(name);
            client.setFdCode(name);
            Client dbClient = clientRepository.findByFdCode(name);
            if (dbClient == null) {
                client.setFdSecret("123456");
                clientRepository.save(client);
            }
        });
    }


    private Client getClient(String clientId) {
        return clientRepository.findByFdCode(clientId);
    }

    private Client getClient(String clientId, String secret) {
        Client client = this.getClient(clientId);
        if (client == null || !client.getFdSecret().equals(secret)) {
            throw new ClientInvalidException("Client not found or Client secret is error!");
        }
        return client;
    }

}
